﻿using Common.FrontEnd;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Util.Machlearn;

namespace FrontEnd
{
    /// <summary>
    /// A Data object that holds data of primitive type double.
    /// </summary>
    public class DoubleData: OVector, IData
    {
        private int sampleRate;
        private long firstSampleNumber;
        private long collectTime;


        /**
        /// Constructs a new <code>Data</code> object with values only. All other internal fields like
        /// sampling rate etc. are initialized to -1.
        /// @param values
         */
        public DoubleData(double[] values) 
            :base(values)
        {
           
        }


        /**
        /// Constructs a Data object with the given values, collect time, and first sample number.
         *
        /// @param values            the data values
        /// @param sampleRate        the sample rate of the data
        /// @param firstSampleNumber the position of the first sample in the original data
         */
        public DoubleData(double[] values, int sampleRate,
                          long firstSampleNumber) 
            :base(values)
        {
            this.sampleRate = sampleRate;
            this.collectTime = firstSampleNumber* 1000 / sampleRate;
            this.firstSampleNumber = firstSampleNumber;
        }

        public DoubleData(float[] values, int sampleRate,
                          long firstSampleNumber)
            : base(values)
        {
            this.sampleRate = sampleRate;
            this.collectTime = firstSampleNumber * 1000 / sampleRate;
            this.firstSampleNumber = firstSampleNumber;
        }

        /**
        /// Constructs a Data object with the given values, collect time, and first sample number.
         *
        /// @param values            the data values
        /// @param sampleRate        the sample rate of the data
        /// @param collectTime       the time at which this data is collected
        /// @param firstSampleNumber the position of the first sample in the original data
         */
        public DoubleData(double[] values, int sampleRate,
                          long collectTime, long firstSampleNumber) 
            :base(values)
        {
            this.sampleRate = sampleRate;
            this.collectTime = collectTime;
            this.firstSampleNumber = firstSampleNumber;
        }

        /**
        /// @return a string that describes the data.
         */
        override
        public String ToString() 
        {
            //return ("DoubleData: " + sampleRate + "Hz, first sample #: " +
            //        firstSampleNumber + ", collect time: " + collectTime + base.ToString());
            return base.ToString();
        }


        /**
        /// @return the sample rate of the data.
         */
        public int getSampleRate() 
        {
            return sampleRate;
        }


        /**
        /// @return the position of the first sample in the original data. The very first sample number
        /// is zero.
         */
        public long getFirstSampleNumber() 
        {
            return firstSampleNumber;
        }


        /**
        /// Returns the time in milliseconds at which the audio data is collected.
         *
        /// @return the difference, in milliseconds, between the time the audio data is collected and
        ///         midnight, January 1, 1970
         */
        public long getCollectTime() 
        {
            return collectTime;
        }

        public DoubleData Clone()
        {
            try 
            {
                DoubleData data = (DoubleData)base.MemberwiseClone();
                data.sampleRate = sampleRate;
                data.collectTime = collectTime;
                data.firstSampleNumber = firstSampleNumber;
                return data;
            } 
            catch (Exception e) 
            {
                throw e;
            }
        }

    }
}
